package com.dxf.chepter09

/**
 *  match 模式匹配 比java的switch 更加强大
 *
 *  语法:
 *    采用match 关键字 每个分支采用case 关键字进行声明,当需要匹配时,会从第一个case分支开始,
 *    如果匹配成功.执行对应逻辑代码,匹配失败.继续执行下一个分支判断,如果所有case都不匹配
 *    执行 case _ 分支,类似java中的default
 *
 *    ======================================
 *
 *    注意事项
 *    1 如果没有匹配到 异常  scala.MatchError
 *    2 => 后面可以是代码块
 *    3 case 匹配可以任意类型
 *    4 case 可以对一个点的匹配,也可以对一个范围匹配(可以if语句) ==> 守卫
 *
 *
 *    =========================================
 *
 *
 *    守卫:
 *
 *    如果想要表达匹配某个范围的数据,需要再匹配模式中增加条件守卫
 *
 *    即 scala的match 可以对一个点的匹配,也可以对一个范围的匹配
 *
 *
 *
 *
 *
 *    可以在case 后面添加语法    case _ if oper.toString.equals("8") => println("ok8")    -->守卫  oper.toString.equals("8")
 *  =========================================================
 *
 *  match中的case:
 *    ch match {
 *      //aaa 可以看成是 ch 即   aaa = ch  => println()
 *      case aaa => println()
 *    }
 *
 *  match 在scala中是一个表达式,可以进行类型匹配 ,避免 isInstanceOf[T] 和asInstanceOf[T]
 *    case '+' => ch + 'hello'
 *
 *  match匹配注意事项:
 *       1 Map[String ,Int]  和 Map[Int,String] 是两种不同类型,其它结构类似
 *       2 在进行类型匹配时,编译器会预先检测是否有可能匹配,如果不能匹配会报错
 *       3 case i:Int => i    意思是把i = obj ,再判断类型  即 (i=obj) :Int  => i
 *       4 case_ 出现在match中间,表示隐藏变量名,即不使用,而不是表示默认匹配
 * =============================================================
 * 数组匹配
 * 1 Array(0) 匹配只有一个元素且为0的数组
 * 2 Array(x,y) 匹配数据有两个,并将两个元素赋值为x和y,当然也可以 3个匹配 Array(x,y,z)
 * 3 Array(0,_*) 匹配数组以0开始
 *
 *
 * ==============================================================
 *
 *
 * 匹配列表
 *  0 :: Nil    类比  Array(0)
 *  x :: y :: Nil    类比  Array(x,y)
 *  0 :: tail    类比  Array(0,_*)
 *  x :: Nil    类比  Array(x)
 *
 *================================
 *
 *  对象匹配:
 *   什么才算是对象匹配?
 *   1 case中对象的unapply方法(对象提取器)返回some集合为匹配成功
 *   2 返回none为匹配失败
 *
 *
 *
 *
 *
 *
 */
object T113_对象匹配 {


  def main(args: Array[String]): Unit = {

    val number=36.0
    number match {
        // case Square(n)  运行机制
        //1 当匹配到这里时
        //2 调用Square的 unapply(z:Double)方法,z的值就是number  36
        //3 如果对象提取器unapply(z:Double) 返回的是some(6) 则匹配成功,同时将6赋值给 Square(n)的n
      case Square(n) =>println(n)
      case _ =>println("nothing")
    }


    /**
     *  Square(n) 说明:
     *
     *    1 构造对象是   Square(n)  会调用 apply方法 如 val n1 = Square(5)
     *    2 对象匹配是   Square(n)  会调用 unapply方法   这时 n就是 被match的值
     *
     */


    val value: Any = Aaa(1)
    println(value)




  }


}


object Square{
  //unapply 对象提取器
  //z 就是要匹配的值 number
  //返回 Some 就是匹配成功
  //返回 None 匹配不成功
  def unapply(z:Double):Option[Double] = {
    println("unapply方法被调用")
    Some(math.sqrt(z))//提取器
    None
  }
  def apply(z:Double):Double = z*z  //可以理解为构造器

}


object Aaa{
  def apply(i: Int) = i
}
